angular.module('fs.component').directive('fsDashboardDraggable', fsDashboardDraggable)
angular.module('fs.component').provider('dashboardPanelService', dashboardPanelServiceProvider);
angular.module('fs.component').factory('componentService', componentService);
componentService.$inject = ['$document', '$timeout'];
function componentService() {
    return {
        initComponent: function (componentController, fsGridController) {
            componentController.focus = function () {
                return fsGridController.focus();
            };
            componentController.blur = function () {
                return fsGridController.blur();
            };
            componentController.isChanged = function () {
                return fsGridController.isChanged();
            };
            componentController.getTooltipMessage = function () {
                componentController.tooltip = fsGridController.getTooltipMessage();
                return componentController.tooltip;
            };
            componentController.isActive = function (grid) {
                return fsGridController.isActive(grid);
            };
            componentController.isShow = function (grid) {
                return fsGridController.isShow(grid);
            };
            componentController.isReadonly = function (grid) {
                return fsGridController.isReadonly(grid);
            };
            componentController.showStyle = function (grid) {
                return fsGridController.showStyle(grid);
            };
        },
        watchGridScope: function (fsGridController, watchExp, listener) {
            if (angular.isFunction(watchExp)) {
                watchExp;
            }

            // TODO: $watch undefined
            return fsGridController.getGridAppScope().$watch(watchExp, function (newVal, oldVal, scope) {
                listener(newVal, oldVal, scope);
            });
        },
        getTopFormCtrl: function (formCtrl) {
            return formCtrl && formCtrl.$$parentForm && formCtrl.$$parentForm[formCtrl.$name] ? this.getTopFormCtrl(formCtrl.$$parentForm) : formCtrl;
        },
        registerFormCtrls: function (topFormCtrl, formCtrl) {
            if (!formCtrl || topFormCtrl == formCtrl) return;
            if (topFormCtrl._formCtrls && topFormCtrl._formCtrls[formCtrl.$$parentForm.$name + '-' + formCtrl.$name]) {
                return;
            }
            topFormCtrl._formCtrls = topFormCtrl._formCtrls || {};
            topFormCtrl._formCtrls[formCtrl.$$parentForm.$name + '-' + formCtrl.$name] = formCtrl;
            if (formCtrl.$$parentForm && formCtrl.$$parentForm[formCtrl.$name]) {
                this.registerFormCtrls(formCtrl.$$parentForm, formCtrl);
            }
        },
        destoryFormCtrls: function (formCtrls, currentFormCtrl) {
            var _this = this;
            angular.forEach(formCtrls, function (formCtrl) {
                if (formCtrl && formCtrl._formCtrls && formCtrl._formCtrls[currentFormCtrl.$$parentForm.$name + '-' + currentFormCtrl.$name]) {
                    delete formCtrl._formCtrls[currentFormCtrl.$$parentForm.$name + '-' + currentFormCtrl.$name];
                    _this.destoryFormCtrls(formCtrl._formCtrls, currentFormCtrl);
                }
            });
        },
        getFormCtrls: function (formCtrl) {
            var _this = this;
            if (!formCtrl) return null;
            var topFormCtrl = _this.getTopFormCtrl(formCtrl);
            return topFormCtrl._formCtrls;
        },
        prepareGridRules: function ($parse, gridConfig, validatorConfig) {
            if (!gridConfig || !gridConfig.model || !(validatorConfig || gridConfig.ruleInfos)) {
                return;
            }
            var commonRules,
                modelName = gridConfig.model,
                dynamicParamRuleInfos = {};
            dynamicParamRuleInfos.ruleInfos = gridConfig.ruleInfos;
            commonRules = $parse(modelName)(validatorConfig);
            gridConfig.rules = commonRules || dynamicParamRuleInfos;
            if (gridConfig.rules) {
                gridConfig.rules.field = gridConfig.model;
                angular.forEach(gridConfig.rules.ruleInfos, function (rule) {
                    if (gridConfig.filter == 'encode') {
                        rule.needFilterModelValue = true;
                    }
                    if (angular.lowercase(rule.ruleName) == 'required' || (rule.conditionValue && angular.lowercase(rule.ruleName) == 'dependent')) {
                        gridConfig.isRequired = true;
                        if (gridConfig.dynamicParameter) gridConfig.isNecessary = true;
                    }
                });
            }
            gridConfig.hasPreparedGridRules = true;
        },
        buildCompareResult: function ($parse, $filter, fsGridLayoutController, gridConfig, value, oldValue) {
            if (gridConfig.comparable === false || !gridConfig.model) {
                return;
            }
            var compareResult = {};
            compareResult.hasChanged = true;
            if (gridConfig.type == 'sensitive') {
                oldValue = oldValue || '';
                compareResult.tooltip = [formatService.formatSst(oldValue, gridConfig.options)];
            } else if (gridConfig.filter) {
                compareResult.tooltip = [$parse(gridConfig.model + ' | ' + gridConfig.filter)(fsGridLayoutController.fsVerifyModel)];
            } else if (gridConfig.type == 'select' || gridConfig.type == 'radio' || gridConfig.type == 'checkbox') {
                oldValue = oldValue || '';
                var tooltip = oldValue;
                if (gridConfig.options) {
                    if (angular.isString(gridConfig.options)) {
                        gridConfig.options = $parse(gridConfig.options)(gridConfig.appScope);
                    }
                    if (angular.isString(gridConfig.options.data)) {
                        gridConfig.options.data = $parse(gridConfig.options.data)(gridConfig.appScope);
                    }
                    if (gridConfig.options.data && gridConfig.options.data.length) {
                        for (var i = 0; i < gridConfig.options.data.length; i++) {
                            var obj = gridConfig.options.data[i];
                            if (obj.value == oldValue) {
                                tooltip = $filter('translate')(obj.label);
                                break;
                            }
                        }
                    }
                }
                compareResult.tooltip = [tooltip];
            } else if (angular.isDate(oldValue)) {
                if (gridConfig.type == 'date' || gridConfig.type == 'date-range') {
                    if (gridConfig.options && gridConfig.options.minMode == 'year') {
                        compareResult.tooltip = [formatService.formatDate(oldValue, gridConfig.format || 'yyyy')];
                    } else if (gridConfig.options && gridConfig.options.minMode == 'month') {
                        compareResult.tooltip = [formatService.formatDate(oldValue, gridConfig.format || 'yyyy-MM')];
                    } else {
                        compareResult.tooltip = [formatService.formatDate(oldValue, gridConfig.format || 'date')];
                    }
                } else if (gridConfig.type == 'datetime' || gridConfig.type == 'datetime-range') {
                    compareResult.tooltip = [formatService.formatDate(oldValue, gridConfig.format || 'timestamp')];
                } else if (gridConfig.type == 'time') {
                    compareResult.tooltip = [formatService.formatDate(oldValue, gridConfig.format || 'HH:mm:ss')];
                } else {
                    compareResult.tooltip = [formatService.formatDate(oldValue, gridConfig.format || 'longTimestamp')];
                }
            } else {
                compareResult.tooltip = [angular.isObject(oldValue) ? angular.toJson(oldValue) : oldValue];
            }
            return compareResult;
        }
    };
}


fsDashboardDraggable.$inject = ['$document', '$timeout'];
function fsDashboardDraggable($document, $timeout) {
    return {
        restrict: 'A',
        link: function ($scope, element, $attrs, ctrls) {
        }
    };
}

dashboardPanelServiceProvider.$inject = [];
function dashboardPanelServiceProvider() {
    var provider = this;
    provider.panelConfigs = {};
    provider.loadingCount = 0;
    provider.loadingInstance = null;
    provider.setpanelConfig = function (name, options) {
        provider.panelConfigs[name] = options;
    };
    provider.panelOptions = {
        size: 'lg',
        blocked: false,
        backdrop: false,
        keyboard: false,
        animation: false
        // windowTemplateUrl : 'fs/template/modal/window.html',
        // appendTo : provider.appendTo,
        // scope : provider.scope
        // backdropClass: '',
        // controller: '',
        // controllerAs: '',
        // openedClass:'',
        // resolve:{},
        // template: '',
        // templateUrl: '',
        // windowClass: '',
        // resolve : object or function
    };
    provider.$get = dashboardPanelService;
    dashboardPanelService.$inject = ['$rootScope', '$stateParams', '$ocLazyLoad', '$uibModal', '$uibPosition', '$window', '$document', '$q', '$log', '$timeout', 'Constants', 'modalService', 'routerService', 'ajaxServiceFactory', 'storageService'];
    function dashboardPanelService($rootScope, $stateParams, $ocLazyLoad, $uibModal, $uibPosition, $window, $document, $q, $log, $timeout, Constants, modalService, routerService, ajaxServiceFactory, storageService) {
        var log = $log.getInstance('dashboardPanelService');
        provider.panelOptions.scope = $rootScope;
        function showPanelHelp(panelConfig) {
            if (panelConfig) {
                modalService.openInfoDialogs({
                    'messages': panelConfig.helpMessages
                });
            }
        }
        function removePanel(panelConfig) {
            if (panelConfig) {
                delete panelConfig.isAdded;
                panelConfig.isRemoved = true;
            }
            if (panelConfig.panelInstance) {
                panelConfig.panelInstance.close();
            }
        }
        function addPanel(panelConfig) {
            var panelInstance, promise;
            loadDependentFiles(panelConfig).then(function (response) {
                if (response.panelViewLinkurls && response.panelViewLinkurls.data) {
                    $stateParams.authorization = buildAuthService($rootScope, Constants, ajaxServiceFactory, response.panelViewLinkurls.data || {});
                }
                if (response.panelViewRes && response.panelViewRes.data) {
                    storageService.setItemToSession(Constants.SESSION_I18N_RESOURES, response.panelViewRes.data);
                    // $rootScope.$emit(Constants.NOTIFY_CHANGE_LANGUAGE);
                }
                if (response.panelViewRes && response.panelViewValidate.data && response.panelViewValidate.data.resources) {
                    storageService.setItemToSession(Constants.SESSION_I18N_RESOURES, response.panelViewValidate.data.resources);
                    // $rootScope.$emit(Constants.NOTIFY_CHANGE_LANGUAGE);
                }
                panelConfig.bodyStyle = {
                    width: '100%',
                    height: (panelConfig.minHeight - 25) + 'px',
                    'overflow': 'hidden'
                };
                panelConfig.dashboardTemplateUrl = panelConfig.panelViewTemplate.replace('${theme}', routerService.getTheme());
                var panelOptions = angular.extend({
                    appendTo: panelConfig.appendTo,
                    templateUrl: 'fs/template/modal/dashboard/panel.html',
                    size: [panelConfig.minWidth, panelConfig.minHeight],
                    controller: response.panelViewCtrljs.controller,
                    controllerAs: response.panelViewCtrljs.controllerAs,
                    windowTopClass: panelConfig.windowTopClass,
                    animation: false,
                    isDashboard: true,
                    resolve: {
                        panelConfig: panelConfig,
                        layoutConfig: response.panelViewValidate ? response.panelViewLayout.data : null,
                        i18nConfig: response.panelViewRes ? response.panelViewRes.data : null,
                        authService: $stateParams.authorization,
                        validatorConfig: (response.panelViewValidate && response.panelViewValidate.data) ? response.panelViewValidate.data.rules : null
                    }
                }, provider.panelOptions);
                panelInstance = $uibModal.open(panelOptions);
                panelConfig.panelInstance = panelInstance;
                panelConfig.isAdded = true;
                delete panelConfig.isRemoved;
                return panelInstance;
            }, function (e) {
                console.log(e);
            });
        }

        function buildAuthService($rootScope, Constants, ajaxServiceFactory, authorizationConfig) {
            var authorizationServices = {}, authService, emptyServiceNames = [];
            angular.forEach(authorizationConfig, function (value, key) {
                if (value == '') {
                    emptyServiceNames.push(key);
                } else {
                    authorizationServices[key] = {
                        url: value,
                        method: 'post',
                        'cache': provider.cacheAuthorization
                    };
                }
            });
            authService = ajaxServiceFactory.buildAjaxService(authorizationServices) || {};
            angular.forEach(emptyServiceNames, function (value, key) {
                authService[value] = angular.noop;
            });
            return authService;
        }

        function loadDependentFiles(panelConfig) {
            var ajaxConfig = {}, promises = {}, ajaxService, defer = $q.defer();
            $ocLazyLoad.load(panelConfig.panelViewCtrljs.replace('${theme}', routerService.getTheme()), {
                cache: true
            }).then(function (response) {
                defer.resolve({
                    controller: panelConfig.panelViewCtrljs.split('/').shift() + ".dashboard." + panelConfig.panelViewCtrljs.split('/').pop().split('.').shift(),
                    controllerAs: 'panelController'
                });
            }, function (e) {
                defer.reject(e);
            });
            promises.panelViewCtrljs = defer.promise;
            if (panelConfig.panelViewLayout) {
                ajaxConfig.loadViewConfig = {
                    'url': panelConfig.panelViewLayout.replace('${theme}', routerService.getTheme()),
                    'method': 'get',
                    'cache': false
                };
            }
            if (panelConfig.panelViewRes) {
                ajaxConfig.loadViewRes = {
                    'url': panelConfig.panelViewRes.replace('${theme}', routerService.getTheme()),
                    'method': 'get',
                    'cache': false
                };
            }
            if (panelConfig.panelViewLinkurls) {
                ajaxConfig.loadViewLinkurls = {
                    'url': panelConfig.panelViewLinkurls.replace('${theme}', routerService.getTheme()),
                    'method': 'get',
                    'cache': false
                };
            }
            if (panelConfig.panelViewValidate) {
                ajaxConfig.loadViewValidate = {
                    'url': panelConfig.panelViewValidate.replace('${theme}', routerService.getTheme()),
                    'method': 'get',
                    'cache': false
                };
            }
            ajaxService = ajaxServiceFactory.buildAjaxService(ajaxConfig);
            if (panelConfig.panelViewLayout) {
                promises.panelViewLayout = ajaxService.loadViewConfig();
            }
            if (panelConfig.panelViewRes) {
                promises.panelViewRes = ajaxService.loadViewRes();
            }
            if (panelConfig.panelViewLinkurls) {
                promises.panelViewLinkurls = ajaxService.loadViewLinkurls();
            }
            if (panelConfig.panelViewValidate) {
                promises.panelViewValidate = ajaxService.loadViewValidate();
            }
            return $q.all(promises);
        }
        return {
            addPanel: addPanel,
            removePanel: removePanel,
            showPanelHelp: showPanelHelp
        };
    }
}